# @Version        : 1.0
# @Update Time    : 2025/2/9 13:12
# @File           : wx_oauth.py
# @IDE            : PyCharm
# @Desc           : 文件描述信息
import io
import httpx
import qrcode
from fastapi import APIRouter, HTTPException
from fastapi.responses import StreamingResponse
from fastapi_utils.cbv import cbv
from src.config import settings
from src.core.base_controller import BaseController

router = APIRouter()


@cbv(router)
class WxOauthController(BaseController):
    @router.get("/login", summary="微信登录")
    async def wx_login(self):
        state = "STATE"  # 可以考虑动态生成或从参数中获取
        auth_url = (
            f"https://open.weixin.qq.com/connect/qrconnect"
            f"?appid={settings.wx.WX_APPID}"
            f"&redirect_uri={settings.wx.WX_REDIRECT_URI}"
            f"&response_type=CODE&scope=snsapi_login"
            f"&state={state}#wechat_redirect"
        )
        img = qrcode.make(auth_url)
        buf = io.BytesIO()
        img.save(buf)
        buf.seek(0)
        return StreamingResponse(buf, media_type="image/png")

    @router.get("/callback", summary="微信回调")
    async def wx_callback(self, code: str):
        token_url = "https://api.weixin.qq.com/sns/oauth2/access_token"
        params = {
            "appid": settings.wx.WX_APPID,
            "secret": settings.wx.WX_SECRET,
            "code": code,
            "grant_type": "authorization_code",
        }

        try:
            async with httpx.AsyncClient() as client:
                resp = await client.get(token_url, params=params)
                resp.raise_for_status()
                token_data = resp.json()

            if "errcode" in token_data:
                raise HTTPException(
                    status_code=400,
                    detail=f"Error getting access token: {token_data['errmsg']}",
                )

            user_url = "https://api.weixin.qq.com/sns/userinfo"
            user_params = {
                "access_token": token_data["access_token"],
                "openid": token_data["openid"],
                "lang": "zh_CN",
            }

            async with httpx.AsyncClient() as client:
                user_resp = await client.get(user_url, params=user_params)
                user_resp.raise_for_status()
                user_info = user_resp.json()

            if "errcode" in user_info:
                raise HTTPException(
                    status_code=400,
                    detail=f"Error getting user info: {user_info['errmsg']}",
                )

            return {
                "openid": user_info["openid"],
                "nickname": user_info["nickname"],
                "avatar": user_info["headimgurl"],
            }

        except httpx.HTTPStatusError as e:
            raise HTTPException(status_code=e.response.status_code, detail=str(e))
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))
